﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows.Forms;
using BL;
using BL.Model.Request;
using DAL.Model;

namespace UI.MainFunctions
{
    public partial class frmReceipt : Base.DialogViewBase
    {
        private MasterSession _session;
        private ReceiptController _receiptController;
        private CustomerController _customerController;
        private DocumentSeqNoHelper _documentSeqNoHelper;

        // This variable contains form status has changed or not
        private bool _isDirty;

        public int? ReceiptId = null;
        public List<int> StockOutIds;
        private Collection<StockOut> _stockOuts;

        #region Constructor

        public frmReceipt()
        {
            InitializeComponent();
        }

        #endregion

        protected override void InitializeBO()
        {
            base.InitializeBO();
            _session = new MasterSession();
            _receiptController = new ReceiptController(_session);
            _customerController = new CustomerController(_session);
            _documentSeqNoHelper = new DocumentSeqNoHelper("Receipt", _session);
        }

        protected override void PopulateData()
        {
            base.PopulateData();

            InitForm();
        }

        private void btnSave_Click(object sender, EventArgs e)
        {
            #region validate

            var validated = true;

            string documentNo = txtReceiptNo.EditValue.ToString();
            int customerId = 0;

            if (string.IsNullOrWhiteSpace(documentNo))
            {
                txtReceiptNo.ErrorText = "Nhập mã phiếu";
                validated = false;
            }
            else
            {
                txtReceiptNo.ErrorText = string.Empty;
            }

            if (cboCustomers.EditValue == null ||
                !int.TryParse(cboCustomers.EditValue.ToString(), out customerId))
            {
                cboCustomers.ErrorText = "Chọn khách hàng";
                validated = false;
            }
            else
            {
                cboCustomers.ErrorText = string.Empty;
            }

            var detail = _receiptController.Detail(documentNo);
            if (detail != null && ReceiptId != detail.Id)
            {
                txtReceiptNo.ErrorText = "Mã phiếu đã tồn tại";
                validated = false;
            }
            else
            {
                txtReceiptNo.ErrorText = string.Empty;
            }

            if (!validated)
            {
                return;
            }

            #endregion

            var receipt = new Receipt
            {
                DocumentNo = documentNo,
                ReceiptedDate = dpCreateDate.DateTime,
                CustomerId = customerId,
                Payer = !string.IsNullOrEmpty(txtPayer.Text) ? txtPayer.Text.Trim() : string.Empty,
                ReceiptAmount = !string.IsNullOrEmpty(txtAmount.Text) ? decimal.Parse(txtAmount.Text) : 0,
                AllowanceCharge = !string.IsNullOrEmpty(txtDiscount.Text) ? decimal.Parse(txtDiscount.Text) : 0,
                TotalAmount = !string.IsNullOrEmpty(txtRealAmount.Text) ? decimal.Parse(txtRealAmount.Text) : 0,
                Desciption = !string.IsNullOrEmpty(txtNote.Text) ? txtNote.Text.Trim() : string.Empty,
                Receiver = !string.IsNullOrEmpty(txtReceiver.Text) ? txtReceiver.Text.Trim() : string.Empty,
                Note = !string.IsNullOrEmpty(txtReason.Text) ? txtReason.Text.Trim() : string.Empty,
                StockOuts = _stockOuts
            };
            _receiptController.Create(receipt);
            _documentSeqNoHelper.UpdateDocSeqNo(receipt.DocumentNo);

            _session.CommitChanges();

            if (receipt.Id > 0)
            {
                _isDirty = false;
                ClearForm();
                DialogResult = DialogResult.Yes;
            }

            Close();
        }

        private void btnClose_Click(object sender, EventArgs e)
        {
            Close();
        }

        private void txt_Change(object sender, KeyPressEventArgs e)
        {
            SetChangeData();
        }

        private void frmReceipt_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (!_isDirty)
            {
                return;
            }
            if (MessageBox.Show("Thông tin đã được thay đổi. Bạn có chắc chắn muốn đóng không?",
                                "Thông báo", MessageBoxButtons.OKCancel) == DialogResult.Cancel)
            {
                e.Cancel = true;
            }
        }

        #region Private methods

        void OnEditAmount_EditValueChanged(object sender, EventArgs e)
        {
            int amount;
            int discount;
            int realAmount;
            if(int.TryParse(txtAmount.Value.ToString(), out amount) &&
               int.TryParse(txtDiscount.Value.ToString(), out discount) &&
               int.TryParse(txtRealAmount.Value.ToString(), out realAmount))
            {
                realAmount = amount - discount;
                txtRealAmount.Text = realAmount.ToString();
                btnSave.Enabled = true;
            }
            else
            {
                btnSave.Enabled = false;
            }
        }

        void InitForm()
        {
            dpCreateDate.DateTime = DateTime.Now;
            txtAmount.EditValue = 0;
            txtDiscount.EditValue = 0;
            txtRealAmount.EditValue = 0;

            // Set status of customer combobox base on customer Id parameter exists or not
            cboCustomers.Enabled = StockOutIds == null || !StockOutIds.Any();

            // Set status if this form show detail
            if (ReceiptId.HasValue)
            {
                txtReceiptNo.Enabled = false;
                cboCustomers.Enabled = false;
                txtPayer.Enabled = false;
                txtReceiver.Enabled = false;
                txtAmount.Enabled = false;
                txtReason.Enabled = false;
                txtDiscount.Enabled = false;
                txtNote.Enabled = false;
                btnSave.Enabled = false;
            }
            
            txtReceiptNo.Text = _documentSeqNoHelper.GetNextDocSeqNo();

            LoadCustomer();
            LoadStockOut();
            if (ReceiptId.HasValue)
            {
                LoadData(ReceiptId.Value);
            }
        }

        void ClearForm()
        {
            txtReceiptNo.Text = "";
            cboCustomers.Text = "";
            txtPayer.Text = "";
            txtReceiver.Text = "";
        }

        void LoadCustomer()
        {
            var request = new SearchingRequest
            {
                Keyword = string.Empty,
                IsPaging = false
            };

            var customers = _customerController.Search(request);
            cboCustomers.Properties.DataSource = customers;
            cboCustomers.Properties.DisplayMember = "Name";
            cboCustomers.Properties.ValueMember = "Id";
        }

        void LoadData(int id)
        {
            var receiptDetail = _receiptController.Detail(id);
            if (receiptDetail == null) return;
            txtReceiptNo.Text = receiptDetail.DocumentNo;
            dpCreateDate.DateTime = receiptDetail.ReceiptedDate;
            cboCustomers.SelectedText = receiptDetail.CustomerName;
            txtPayer.Text = receiptDetail.Payer;
            txtAmount.EditValue = receiptDetail.ReceiptAmount;
            txtReason.Text = receiptDetail.Desciption;
            txtReceiver.Text = receiptDetail.Receiver;
            txtDiscount.EditValue = receiptDetail.AllowanceCharge;
            txtNote.Text = receiptDetail.Note;
            txtRealAmount.EditValue = receiptDetail.TotalAmount;
        }

        void LoadStockOut()
        {
            _stockOuts = new Collection<StockOut>();
            if (StockOutIds == null || !StockOutIds.Any())
            {
                return;
            }
            var stockOuts = (from stockOut in _session.StockOuts
                             where StockOutIds.Contains(stockOut.Id)
                             select stockOut);
            foreach (var stockOut in stockOuts)
            {
                _stockOuts.Add(stockOut);
            }

            var so = stockOuts.FirstOrDefault();
            if (so != null)
            {
                cboCustomers.Enabled = false;
                cboCustomers.EditValue = so.CustomerId;
                txtPayer.Text = so.ContactName;
            }
            if (stockOuts.Any())
            {
                txtAmount.EditValue = stockOuts.Sum(x => x.StockOutDetails.Sum(y => y.Amount));
                txtRealAmount.EditValue = txtAmount.EditValue;
            }
        }

        void SetChangeData()
        {
            _isDirty = true;
            btnSave.Enabled = true;
        }

        #endregion
    }
}
